package permission

import (
	"context"
	"fmt"
	"github.com/samber/lo"
	"private-domain-overseas-service/admin/business/api/internal/repository/permission"
	"private-domain-overseas-service/admin/business/api/internal/svc"
	"private-domain-overseas-service/admin/business/api/internal/types"
	"private-domain-overseas-service/pkg/xerr"
	"private-domain-overseas-service/tools/ent"
	"sort"
	"time"

	"github.com/zeromicro/go-zero/core/logx"
)

type AdminRouterListLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

// NewAdminRouterListLogic - 后台菜单查询接口
func NewAdminRouterListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AdminRouterListLogic {
	return &AdminRouterListLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *AdminRouterListLogic) AdminRouterList() (resp *types.AdminRouterListResponse, err error) {
	adminRouterDAO := permission.NewAdminRouterDao(l.ctx, l.svcCtx)

	// 查询所有菜单
	adminRouters, total, err := adminRouterDAO.AdminRouterConditionsAll(nil)
	if err != nil {
		return nil, xerr.ErrCodeMsg(xerr.ServerOperationExceptionError, fmt.Sprintf("查询菜单失败: %v", err))
	}

	// 组装数据
	list := convert(adminRouters)
	// 构建菜单树
	tree := buildMenuTree(list, 0)

	// 按照一级菜单id升序排序
	sort.Slice(tree, func(i, j int) bool {
		return tree[i].AdminRouterOrder < tree[j].AdminRouterOrder
	})

	// 返回数据
	return &types.AdminRouterListResponse{
		Page: &types.PageResponse{
			Total:    int64(total),
			PageSize: int64(len(tree)),
		},
		List: tree,
	}, nil
}

// 递归构建菜单树
func buildMenuTree(list []*types.AdminRouterInfo, pid int64) []*types.AdminRouterInfo {
	var result []*types.AdminRouterInfo
	for _, item := range list {
		if item.AdminRouterPid == pid {
			menu := *item
			// 把子菜单填入children
			menu.Children = buildMenuTree(list, menu.ID)
			// （二级菜单，三级菜单，四级菜单）都按id升序排序
			sort.Slice(menu.Children, func(i, j int) bool {
				return menu.Children[i].AdminRouterOrder < menu.Children[j].AdminRouterOrder
			})
			result = append(result, &menu)
		}
	}
	return result
}

// 组装数据 - ent.AdminRouter 转为 types.AdminRouterInfo
func convert(list []*ent.AdminRouter) []*types.AdminRouterInfo {
	return lo.Map(list, func(item *ent.AdminRouter, _ int) *types.AdminRouterInfo {
		return &types.AdminRouterInfo{
			ID:                    int64(item.ID),
			AdminRouterMenuType:   item.AdminRouterMenuType,
			AdminRouterMenuName:   item.AdminRouterMenuName,
			AdminRouterIconType:   item.AdminRouterIconType,
			AdminRouterIcon:       item.AdminRouterIcon,
			AdminRouterRouteName:  item.AdminRouterRouteName,
			AdminRouterRoutePath:  item.AdminRouterRoutePath,
			AdminRouterComponent:  item.AdminRouterComponent,
			AdminRouterPathParam:  item.AdminRouterPathParam,
			AdminRouterStatus:     item.AdminRouterStatus,
			AdminRouterActiveMenu: item.AdminRouterActiveMenu,
			AdminRouterHideInMenu: item.AdminRouterHideInMenu,
			AdminRouterPid:        item.AdminRouterPid,
			AdminRouterSequence:   item.AdminRouterSequence,
			AdminRouterOrder:      item.AdminRouterOrder,
			AdminRouterI18nKey:    item.AdminRouterI18nKey,
			AdminRouterKeepAlive:  item.AdminRouterKeepAlive,
			AdminRouterConstant:   item.AdminRouterConstant,
			AdminRouterMultiTab:   item.AdminRouterMultiTab,
			AdminRouterHref:       item.AdminRouterHref,
			AdminRouterSystemType: item.AdminRouterSystemType,
			CreateAt:              item.CreateAt.Format(time.DateTime),
			UpdateAt:              item.UpdateAt.Format(time.DateTime),
		}
	})
}
